package com.io.smartappframe.mvc.activity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.io.base.mvc.BaseActivityMVC
import com.io.commonlib.helper.CommonDeviceHelper
import com.io.commonlib.helper.LogHelper
import com.io.commonlib.helper.ToastHelper
import com.io.smartappframe.R
import com.io.smartappframe.databinding.ActivityLanBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.OutputStream
import java.net.ServerSocket
import java.net.Socket
import java.util.concurrent.Executor
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/**
 * Description:局域网通信Demo
 * https://blog.csdn.net/chengliang0315/article/details/54214380
 * https://blog.csdn.net/weixin_39874809/article/details/110572767
 * https://github.com/LostStarTvT/PhoneCall
 * 2021-06-03 13:49
 * @author LiuMin
 */
class LANActivity : BaseActivityMVC<ActivityLanBinding>(), View.OnClickListener {
    //当前设备的IP
    private var deviceIP: String? = null

    //ServerSocket实例
    private var serverSocket: ServerSocket? = null

    //服务器注册的端口号
    private var port = 6666

    //使用线程池，保证单线程处理接收到的数据
    private var executorServiceServer = Executors.newSingleThreadExecutor()
    private var executorServiceClient = Executors.newSingleThreadExecutor()

    //发送数据的客户端Socket
    private var socket: Socket? = null

    private var out: OutputStream? = null

    private var flag = false

    //region 重写父类方法
    override fun initView(savedInstanceState: Bundle?): ActivityLanBinding {
        return ActivityLanBinding.inflate(layoutInflater)
    }

    override fun initData(savedInstanceState: Bundle?) {
        mViewBinding.header.tvTitle.text = "局域网通信"
        mViewBinding.header.ivToolbarBack.setOnClickListener(this)
        mViewBinding.btnStartService.setOnClickListener(this)
        mViewBinding.btnStopService.setOnClickListener(this)
        mViewBinding.btnConnectServer.setOnClickListener(this)
        mViewBinding.btnDisconnectServer.setOnClickListener(this)
        mViewBinding.btnSendMsg.setOnClickListener(this)
        getDeviceIp()
    }

    override fun onClick(v: View?) {
        v?.let {
            if (it.id == R.id.iv_toolbar_back) {
                finish()
            } else if (it.id == R.id.btn_start_service) {//开启服务
                startService()
            } else if (it.id == R.id.btn_stop_service) {//关闭服务
                stopService()
            } else if (it.id == R.id.btn_connect_server) {//连接服务
                clickConnectServer()
            } else if (it.id == R.id.btn_disconnect_server) {//断开连接服务
                disConnectServer()
            } else if (it.id == R.id.btn_send_msg) {//发送消息
                clickSendMsg()
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        flag = false
        executorServiceServer.shutdownNow()
    }
    //endregion

    //region 私有方法
    /**
     * 获取设备ip，并赋值给全局变量
     */
    private fun getDeviceIp() {
        deviceIP = CommonDeviceHelper().getDeviceIp(applicationContext)
        if (deviceIP.isNullOrEmpty()) {
            mViewBinding.tvClientIpContent.text = "获取本机IP失败"
        } else {
            mViewBinding.tvClientIpContent.text = deviceIP
        }
    }

    /**
     * 开启Socket服务
     */
    private fun startService() {
        if (deviceIP.isNullOrEmpty()) {
            ToastHelper.showShortToast(applicationContext, "设备IP获取失败，无法启动服务")
        } else {
            try {
                LogHelper.d(TAG, "启动服务")
                //创建一个ServerSocket对象，并设置监听端口
                serverSocket = ServerSocket(port)
                flag = true
                executorServiceServer.execute { getClientData() }
            } catch (e: Exception) {
                LogHelper.d(TAG, "startService-Exception:${e.message}")
            }
        }
    }

    /**
     * 关闭Socket服务
     */
    private fun stopService() {
        LogHelper.d(TAG, "关闭服务")
        try {
            serverSocket?.close()
            flag = false
        } catch (e: Exception) {
            LogHelper.d(TAG, "stopService-Exception:${e.message}")
        }
    }

    /**
     * 获取客户端发送的数据
     */
    private fun getClientData() {
        LogHelper.d(TAG, "getClientData---------------")
        serverSocket?.let {
            scope.launch(Dispatchers.Default) {
                try {//接收客户端发送的请求
                    val socket: Socket = it.accept()
                    //从Socket对象中得到InputStream对象
                    val inputStream = socket.getInputStream()
                    //获取客户端的ip地址
                    val clientIp = socket.inetAddress.hostName
                    val buffer = ByteArray(10 * 1024)
                    var temp = 0
                    var result = clientIp
                    //从InputStream中读物客户端发送的数据
                    while (flag) {
                        temp = inputStream.read(buffer)
                        if (temp != -1) {
                            val str = String(buffer, 0, temp)
                            result += str
                            LogHelper.i(TAG, "getClientData:${str}")
                            runOnUiThread{
                                mViewBinding.tvReceiveMsgContent.setText(result)
                            }
                        }
                    }
                } catch (e: Exception) {
                    LogHelper.i(TAG, "getClientData-Exception:${e.message}")
                }
            }
        }
    }

    /**
     * 客户端通过【ip】和【port】连接服务器
     */
    private fun connectServer(ip: String, port: Int) {
        scope.launch(Dispatchers.IO) {
            try {
                socket = Socket(ip, port)
                out = socket?.getOutputStream()
                LogHelper.d(
                    TAG,
                    "connectServer: isBound: ${socket?.isBound}; isConnected:${socket?.isConnected}"
                )
            } catch (e: Exception) {
                LogHelper.e(TAG, "connectServer--Exception:${e.message}")
            }
        }
    }

    /**
     * 点击连接服务端
     */
    private fun clickConnectServer() {
        val ipText = mViewBinding.etServiceIpContent.text
        if (ipText.isNullOrEmpty()) {
            ToastHelper.showShortToast(applicationContext, "服务器ip不能为空")
        } else {
            val ip = ipText.toString()
            connectServer(ip, port)
        }
    }

    /**
     * 断开连接服务
     */
    private fun disConnectServer() {
        out?.let {
            try {
                it.close()
            } catch (e: Exception) {
                LogHelper.e(TAG, "disConnectServer--out--Exception:${e.message}")
            }
        }
        socket?.let {
            try {
                if (it.isInputShutdown) {//判断输入流是否为打开状态
                    it.shutdownInput() //关闭输入流
                }
                if (it.isOutputShutdown) {//判断输出流是否为打开状态
                    //关闭输出流，如果是在给对方发送数据，发送完毕之后需要关闭输出，否则对方的InputStream可能会一直在等待状态
                    it.shutdownOutput()
                }
                if (it.isConnected) {//判断是否为连接状态
                    it.close() //关闭Socket
                }
            } catch (e: Exception) {
                LogHelper.e(TAG, "disConnectServer--socket--Exception:${e.message}")
            }
        }
    }

    /**
     * 点击发送消息按钮
     */
    private fun clickSendMsg() {
        val msg = mViewBinding.etSendMsg.text
        if (msg.isNullOrEmpty()) {
            ToastHelper.showShortToast(applicationContext, "发送消息内容不能为空")
        } else {
            val msgStr = msg.toString()
            executorServiceClient.execute {
                sendMsg(msgStr)
            }
        }
    }

    /**
     * 发送消息
     */
    private fun sendMsg(msg: String) {
        out?.let {
            LogHelper.d(TAG, "sendMsg--${msg}")
            scope.launch(Dispatchers.IO) {
                try {
                    it.write(msg.toByteArray())
                    it.flush()
                } catch (e: Exception) {
                    LogHelper.d(TAG, "sendMsg--Exception:${e.message}")
                }
            }
        }
    }
    //endregion
}